home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Extras / Development / Example_Code_v37 / SCSI / modesense.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-27  |  7.1 KB  |  213 lines

  1. /*
  2.  * Copyright (C) 1990-1999 Amiga, Inc.
  3.  * All rights reserved
  4.  */
  5.  
  6. /*
  7.  * The following program demonstrates the use of the HD_SCSICmd to send a
  8.  * MODE SENSE to a unit on the requested device (default scsi.device).  This
  9.  * code can be easily modified to send other commands to the drive.
  10.  *
  11.  * compile under Lattice using 'lc -cfist -L modesense'
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16.  
  17. #include <exec/types.h>
  18. #include <exec/memory.h>
  19. #include <exec/io.h>
  20. #include <devices/timer.h>
  21. #include <devices/scsidisk.h>
  22. #include <libraries/dosextens.h>
  23.  
  24. #include <clib/exec_protos.h>
  25. #include <clib/alib_protos.h>
  26.  
  27. #define BUFSIZE 256
  28.  
  29. UBYTE *buffer;            /* a data buffer used for mode sense data */
  30. struct IOStdReq SCSIReq;    /* a standard IORequest structure */
  31. struct SCSICmd Cmd;        /* where the actual SCSI command goes */
  32. UBYTE  Sense[20];        /* buffer for request sense data */
  33. struct MsgPort Port;        /* our ReplyPort */
  34.  
  35. void ShowSenseData(void);
  36.  
  37. static UBYTE TestReady[] = { 0,0,0,0,0,0 };    /* not used but here for  */
  38. static UBYTE StartUnit[] = { 0x1b,0,0,0,1,0 };    /* illustration of other  */
  39. static UBYTE StopUnit[] =  { 0x1b,0,0,0,0,0 };    /* commands.          */
  40.  
  41. static UBYTE ModeSense[]={ 0x1a,0,0xff,0,254,0 }; /* the command being sent */
  42.  
  43. void main(int argc, char **argv) {
  44.     int unit,tval,i;
  45.     char *dname = "scsi.device";
  46.     UBYTE *tbuf;
  47.  
  48.     if( (argc < 2) || (argc > 3) ) {
  49.     printf("Usage: %s unit [xxxx.device]\n",argv[0]);
  50.     exit(100);
  51.     }
  52.  
  53.     unit = atoi( argv[1] );
  54.     if ( argc == 3 ) dname = argv[2];
  55.  
  56.     buffer = (UBYTE *) AllocMem( BUFSIZE, MEMF_PUBLIC|MEMF_CLEAR );
  57.     if (!buffer) { printf("Couldn't get memory\n"); exit(100); }
  58.  
  59.     Port.mp_Node.ln_Pri = 0;            /* setup the ReplyPort */
  60.     Port.mp_SigBit      = AllocSignal(-1);
  61.     Port.mp_SigTask     = (struct Task *)FindTask(0);
  62.     NewList( &(Port.mp_MsgList) );
  63.  
  64.     SCSIReq.io_Message.mn_ReplyPort = &Port;
  65.  
  66.     if (OpenDevice( dname, unit, &SCSIReq, 0))  {
  67.     printf("Couldn't open unit %ld on %s\n",unit,dname);
  68.     FreeMem( buffer,BUFSIZE );
  69.     exit(100);
  70.     }
  71.  
  72.     SCSIReq.io_Length  = sizeof(struct SCSICmd);
  73.     SCSIReq.io_Data    = (APTR)&Cmd;
  74.     SCSIReq.io_Command = HD_SCSICMD;    /* the command we are sending    */
  75.  
  76.     Cmd.scsi_Data = (UWORD *)buffer;    /* where we put mode sense data    */
  77.     Cmd.scsi_Length = 254;        /* how much we will accept    */
  78.     Cmd.scsi_CmdLength = 6;        /* length of the command    */
  79.     Cmd.scsi_Flags = SCSIF_AUTOSENSE|SCSIF_READ;
  80.                     /* do automatic REQUEST_SENSE    */
  81.                     /* set expected data direction     */
  82.     Cmd.scsi_SenseData =(UBYTE *)Sense;    /* where sense data will go    */
  83.     Cmd.scsi_SenseLength = 18;        /* how much we will accept    */
  84.     Cmd.scsi_SenseActual = 0;        /* how much has been received    */
  85.  
  86.     Cmd.scsi_Command=(UBYTE *)ModeSense;/* issuing a MODE_SENSE command    */
  87.     DoIO( &SCSIReq );            /* send it to the device driver    */
  88.     if(Cmd.scsi_Status) ShowSenseData(); /* if bad status then show it    */
  89.  
  90.     else {
  91.     printf("\nBlock descriptor header\n");
  92.     printf("=======================\n");
  93.     printf("Mode Sense data length  = %d\n",(short)buffer[0]);
  94.     printf("Block descriptor length = %d\n",(short)buffer[3]);
  95.     tbuf = &buffer[4];
  96.     printf("Density code            = %d\n",(short)tbuf[0]);
  97.     tval = (tbuf[1]<<16) + (tbuf[2]<<8) + tbuf[3];
  98.     printf("Number of blocks        = %ld\n",tval);
  99.     tval = (tbuf[5]<<16) + (tbuf[6]<<8) + tbuf[7];
  100.     printf("Block size              = %ld\n",tval);
  101.  
  102.     tbuf += buffer[3];        /* move to page descriptors */
  103.  
  104.     while( (tbuf - buffer) < buffer[0] ) {
  105.         switch ( tbuf[0] & 0x7f ) {
  106.         case 1:
  107.         printf("\nError Recovery Parameters\n");
  108.         printf("=========================\n");
  109.         printf("Page length             = %d\n",(short)tbuf[1]);
  110.         printf("DISABLE CORRECTION      = %d\n",(short)tbuf[2]&1);
  111.         printf("DISABLE XFER ON ERROR   = %d\n",(short)(tbuf[2]>>1)&1);
  112.         printf("POST ERROR              = %d\n",(short)(tbuf[2]>>2)&1);
  113.         printf("ENABLE EARLY CORRECTION = %d\n",(short)(tbuf[2]>>3)&1);
  114.         printf("READ CONTINUOUS         = %d\n",(short)(tbuf[2]>>4)&1);
  115.         printf("TRANSFER BLOCK          = %d\n",(short)(tbuf[2]>>5)&1);
  116.         printf("AUTO READ REALLOCATION  = %d\n",(short)(tbuf[2]>>6)&1);
  117.         printf("AUTO WRITE REALLOCATION = %d\n",(short)(tbuf[2]>>7)&1);
  118.         printf("Retry count             = %d\n",(short)tbuf[3]);
  119.         printf("Correction span         = %d\n",(short)tbuf[4]);
  120.         printf("Head offset count       = %d\n",(short)tbuf[5]);
  121.         printf("Data strobe offset count= %d\n",(short)tbuf[6]);
  122.         printf("Recovery time limit     = %d\n",(short)tbuf[7]);
  123.         tbuf += tbuf[1]+2;
  124.         break;
  125.  
  126.         case 2 :
  127.         printf("\nDisconnect/Reconnect Control\n");
  128.         printf("============================\n");
  129.         printf("Page length             = %d\n",(short)tbuf[1]);
  130.         printf("Buffer full ratio       = %d\n",(short)tbuf[2]);
  131.         printf("Buffer empty ratio      = %d\n",(short)tbuf[3]);
  132.         tval = (tbuf[4]<<8)+tbuf[5];
  133.         printf("Bus inactivity limit    = %d\n",tval);
  134.         tval = (tbuf[6]<<8)+tbuf[7];
  135.         printf("Disconnect time limit   = %d\n",tval);
  136.         tval = (tbuf[8]<<8)+tbuf[9];
  137.         printf("Connect time limit      = %d\n",tval);
  138.         tval = (tbuf[10]<<8)+tbuf[11];
  139.         printf("Maximum burst size      = %d\n",tval);
  140.         printf("Disable disconnection   = %d\n",(short)tbuf[12]&1);
  141.         tbuf += tbuf[1]+2;
  142.         break;
  143.  
  144.         case 3:
  145.         printf("\nDevice Format Parameters\n");
  146.         printf("========================\n");
  147.         printf("Page length             = %d\n",(short)tbuf[1]);
  148.         tval = (tbuf[2]<<8)+tbuf[3];
  149.         printf("Tracks per zone         = %d\n",tval);
  150.         tval = (tbuf[4]<<8)+tbuf[5];
  151.         printf("Alternate sectors/zone  = %d\n",tval);
  152.         tval = (tbuf[6]<<8)+tbuf[7];
  153.         printf("Alternate tracks/zone   = %d\n",tval);
  154.         tval = (tbuf[8]<<8)+tbuf[9];
  155.         printf("Alternate tracks/volume = %d\n",tval);
  156.         tval = (tbuf[10]<<8)+tbuf[11];
  157.         printf("Sectors per track       = %d\n",tval);
  158.         tval = (tbuf[12]<<8)+tbuf[13];
  159.         printf("Bytes per sector        = %d\n",tval);
  160.         tval = (tbuf[14]<<8)+tbuf[15];
  161.         printf("Interleave              = %d\n",tval);
  162.         tval = (tbuf[16]<<8)+tbuf[17];
  163.         printf("Track skew factor       = %d\n",tval);
  164.         tval = (tbuf[18]<<8)+tbuf[19];
  165.         printf("Cylinder skew factor    = %d\n",tval);
  166.  
  167.         tbuf += tbuf[1]+2;
  168.         break;
  169.  
  170.         case 4:
  171.         printf("\nDrive Geometry Parameters\n");
  172.         printf("=========================\n");
  173.         printf("Page length             = %d\n",(short)tbuf[1]);
  174.         tval = (tbuf[2]<<16)+(tbuf[3]<<8)+tbuf[4];
  175.         printf("Number of cylinders     = %ld\n",tval);
  176.         printf("Number of heads         = %d\n",(short)tbuf[5]);
  177.         tval = (tbuf[6]<<16)+(tbuf[6]<<8)+tbuf[8];
  178.         printf("Start write precomp     = %ld\n",tval);
  179.         tval = (tbuf[9]<<16)+(tbuf[10]<<8)+tbuf[11];
  180.         printf("Start reduced write     = %ld\n",tval);
  181.         tval = (tbuf[12]<<8)+tbuf[13];
  182.         printf("Drive step rate         = %d\n",tval);
  183.         tval = (tbuf[14]<<16)+(tbuf[15]<<8)+tbuf[16];
  184.         printf("Landing zone cylinder   = %ld\n",tval);
  185.  
  186.         tbuf += tbuf[1]+2;
  187.         break;
  188.  
  189.         default:
  190.         printf("\nVendor Unique Page Code %2x\n",(short)tbuf[0]);
  191.         printf("==========================\n");
  192.         for( i=0; i<=tbuf[1]+1; i++ )
  193.             printf("%x ",(short)tbuf[i]);
  194.         printf("\n");
  195.         tbuf += tbuf[1]+2;
  196.         }
  197.     }
  198.     }
  199.     CloseDevice( &SCSIReq );
  200.     FreeMem( buffer, BUFSIZE );
  201.     FreeSignal(Port.mp_SigBit);
  202. }
  203.  
  204. void ShowSenseData(void)
  205. {
  206. int i;
  207.  
  208.     for(i=0; i<18; i++)
  209.         printf("%x ",(int)Sense[i]);
  210.     printf("\n");
  211. }
  212.  
  213.